import * as THREE from "three";

class FlyLine {

    constructor(source,target) {
        this.source = source;
        this.target = target;
        this.group = new THREE.Group();
        this.clock = new THREE.Clock()
        this.time = { value: 0 };
        this.startTime = { value: 0 };
        this.startLength = { value: 2 }
        this.isStart = false;
        this.init();
    }

    // 初始化城市类的实例
    init() {
        this.isStart = true; // 城市渲染启动
        this.clock.start()
        // 飞线效果
        this.fly()
    }

    // 飞线效果
    fly() {
        const flyData = {
            source:this.source ,
            target:this.target,
            color: '#35b4ef',
            number: 20,
            size: 0.5,
            period: 1.5,
            opacity: 0.5,
        }


        const source = new THREE.Vector3(flyData.source.x, flyData.source.y, flyData.source.z)
        const target = new THREE.Vector3(flyData.target.x, flyData.target.y, flyData.target.z)
        const center = source.clone().lerp(target, 0.5)
        center.setY(30)
        const distance = parseInt(source.distanceTo(center) + center.distanceTo(target))

        // 定义贝塞尔曲线
        const curve = new THREE.QuadraticBezierCurve3(source, center, target);
        const points = curve.getPoints(distance)

        // 创建组对象
        const group = new THREE.Group()
        for (let i = 0; i < flyData.number; i++) {
            const geometry = new THREE.SphereGeometry(flyData.size, 50, 50)
            const scale = (i + 1) / flyData.number * 0.7 + 0.3
            geometry.applyMatrix4(new THREE.Matrix4().makeScale(scale, scale, scale))// 缩小小球的几何体
            const material = new THREE.MeshBasicMaterial({
                color: flyData.color,
                transparent: true,
                opacity: flyData.opacity,
                depthTest:false,
            })

            const sphere = new THREE.Mesh(geometry, material)
            sphere.renderOrder = 1000
            sphere.position.copy(points[i])
            sphere.updateMatrix()// 更新相对矩阵
            group.add(sphere)

        }

        this.group.add(group)

        setInterval(() => {
            const rate = (this.time.value % flyData.period) / flyData.period
            const position = parseInt(points.length * rate)
            for (let i = 0; i < flyData.number; i++) {
                if (position + i >= points.length) {
                    group.children[i].material.opacity = 0
                } else {
                    group.children[i].material.opacity = flyData.opacity
                    group.children[i].position.copy(points[position + i])
                    group.children[i].updateMatrix()
                }
            }
        }, 50)
    }

    // 数据更新
    updateData = () => {
        if (!this.isStart) return false;
        const dt = this.clock.getDelta();
        this.time.value += dt;
        this.startTime.value += dt;
        if (this.startTime.value >= this.startLength.value) {
            this.startTime.value = this.startLength.value;
        }
    }
}

export default FlyLine;